package com.ahuan.service.Impl;

import com.ahuan.domain.Product;
import com.ahuan.mapper.GoodsMapper;
import com.ahuan.service.GoodsService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOleObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

@Slf4j
@Service
@Transactional
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    GoodsMapper goodsMapper;

    @Override
    public List<Product> queryGoodsList(Integer page, Integer limit) {
        PageHelper.startPage(page, limit);
        List<Product> list = goodsMapper.selectGoodsList();
        return getGoodsLocation(list);
    }

    @Override
    public boolean saveGoods(Product product) {
        product = setGoodsLocation(product);
        setAlarm(product);//设置告警状态
        if (product.getId() == null) {//新增
            goodsMapper.insertGoods(product);
            return product.getId() != null;
        } else {//编辑
            return goodsMapper.updateGoods(product) > 0;
        }

    }

    @Override
    public boolean deleteGoods(Long id) {
        return goodsMapper.deleteGoods(id) > 0;
    }

    @Override
    public void saveBatchProduct(List<Product> cachedDataList) {

    }


    // todo 学习easyExcel 和 POI，做工具类
    @Override
    public boolean saveFiles(List<MultipartFile> files) throws IOException {
        List<Integer> uploadFail = new ArrayList<>();//用于记录失败上传的商品
        int saveSuccess = 0;//用于记录成功上传的商品数

        for (MultipartFile file : files) {
            InputStream inputStream = file.getInputStream();
            Workbook workbook = new XSSFWorkbook(inputStream);
            // 获取第一个sheet
            Sheet sheet = workbook.getSheetAt(0);

            // 指定开始的行和列（假设从第2行、第3列开始读取）
            int startRow = 5;
            int startColumn = 1;

            // 遍历每一行，从指定行开始读取数据
            for (int rowIndex = startRow; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
                Row row = sheet.getRow(rowIndex);
                List<Cell> list = new ArrayList<>();
                //遍历每一列，将每行单元格添加到list中，做进一步处理
                for (int columnIndex = startColumn; columnIndex < row.getLastCellNum(); columnIndex++) {
                    list.add(row.getCell(columnIndex));
                }
                // 处理每一行数据
                Product product = null;
                if (list.size() > 0) {//每一行只要有一个数据,都要进行处理
                    product = toObject(list);
                }
                //处理完成后判断该行数据的入库资格，个别字段不能为空
                if (product != null && !product.isEmpty()) {
                    System.out.println(product);
                    // todo 优化批量插入，以适应大量数据
                    saveGoods(product);
                    saveSuccess++;
                    log.info(product.getId() + "号商品《" + product.getName() + "》入库成功");
                } else {
                    log.info("Excel表的第" + rowIndex + 1 + "条数据不完整，无法入库,请您检查");
                    // todo 记录上传失败的行号，以便进一步处理，如记录日志、跳过该行数据等
                    uploadFail.add(rowIndex);
                }

            }
            inputStream.close();
        }
        return saveSuccess > 0;// todo 这里可以优化，如果成功上传的数据远大于失败的数据则允许上传
    }

    @Override
    public List<Product> ruku(String s, String s1,Integer num) {
        if (goodsMapper.addInventory(s, s1,num) == 0){
            return null;
        }
        return goodsMapper.selectGoodsListById(s);
    }

    /**
     * 将每一行数据转为实体对象
     *
     * @param list
     * @return
     */
    private Product toObject(List<Cell> list) {
        Product product = new Product();
        // 处理每一行数据
        Cell cell;
        int len = list.size();
        //0 < len 防止单元格为空时，造成下标越界，实际的Excel可能出现这种人为情况
        if (0 < len && (cell = list.get(0)) != null) {
            Object o = typeHandler(cell);
            if (o != null) {
                product.setCreateTime(o.toString());//设置时间
            }
        }


        if (1 < len && (cell = list.get(1)) != null) {
            Object o = typeHandler(cell);
            if (o != null) {
                product.setStorehouse((String) o);//设置库房
            }
        }


        if (2 < len && (cell = list.get(2)) != null) {
            Object o = typeHandler(cell);
            if (o != null) {
                product.setShelf((String) o);//设置货架
            }
        }

        if (3 < len && (cell = list.get(3)) != null) {
            Object o = typeHandler(cell);
            if (o != null) {
                product.setNumber((String) o);//设置货架
            }
        }

        if (4 < len && (cell = list.get(4)) != null) {
            Object o = typeHandler(cell);
            if (o != null) {
                product.setName((String) o); //设置名字
            }
        }

        if (5 < len && (cell = list.get(5)) != null) {
            Object o = typeHandler(cell);
            if (o != null) {
                product.setType((String) o);//设置型号
            }
        }

        if (7 < len && (cell = list.get(7)) != null) {
            Object o = typeHandler(cell);
            if (o != null) {
                product.setInventorySum((int) (double) o);//设置入库总量
            }
        }

        if (8 < len && (cell = list.get(8)) != null) {
            Object o = typeHandler(cell);
            if (o != null) {
                product.setInventoryRemove((int) (double) o);//设置出库总量
            }
        }

        if (9 < len && (cell = list.get(9)) != null) {
            Object o = typeHandler(cell);
            if (o != null) {
                product.setInventory((int) (double) o);//设置余量
            }
        }

        if (10 < len && (cell = list.get(10)) != null) {
            Object o = typeHandler(cell);
            if (o != null) {
                product.setUnit((String) o);//设置单位
            }
        }

        if (11 < len && (cell = list.get(11)) != null) {
            Object o = typeHandler(cell);
            if (o != null) {
                product.setCreateUser(1L);//设置经办人
            }
        }


        return product;
    }

    /**
     * 获取单元格数据
     *
     * @param cell
     * @return
     */
    private Object typeHandler(Cell cell) {
        Object result = null;
        switch (cell.getCellType()) {
            case STRING:
                result = cell.getStringCellValue();
                break;
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    result = cell.getDateCellValue();
                } else {
                    result = cell.getNumericCellValue();
                }
                break;
            case BOOLEAN:
                result = cell.getBooleanCellValue();
                break;
            case FORMULA:
                // 处理公式，你可以根据需要进行相应处理
                break;
            case BLANK:
                // 处理空单元格
                break;
            default:
                // 其他类型，根据需要进行相应处理
                break;
        }
        return result;
    }

    /**
     * 设置库存告警
     *
     * @param product
     * @return
     */
    private Product setAlarm(Product product) {
        if (product.getInventory() < product.getAlarmValue()) {//库存小于告警值
            product.setAlarm(true);
        } else {
            product.setAlarm(false);
        }
        return product;
    }


    /**
     * 将location字段拆分为库房，货架，编号
     *
     * @param product
     * @return
     */
    private Product setGoodsLocation(Product product) {
        product.setLocation(product.getStorehouse() + "," + product.getShelf() + "," + product.getNumber());
        return product;
    }


    /**
     * 将location字段拆分为库房，货架，编号
     *
     * @param list
     * @return
     */
    private List<Product> getGoodsLocation(List<Product> list) {
        for (Product product : list) {
            String[] split = product.getLocation().split(",");
            if (split.length != 3) {
                return list;
            }
            product.setStorehouse(split[0]);
            product.setShelf(split[1]);
            product.setNumber(split[2]);
        }
        return list;
    }
}
